package com.dattplace.filter;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.alibaba.fastjson.JSON;
import com.dattplace.cache.CacheFacade;
import com.dattplace.model.User;
import com.dattplace.service.ITokenService;
import com.dattplace.service.IUserService;
import com.dattplace.util.RequestContext;


@WebFilter(urlPatterns = { "/restful/*" })
public class UserSessionFilter implements Filter {

	private static Logger logger = Logger.getLogger(UserSessionFilter.class);
	private static final List<String> WHITE_LIST = new ArrayList<String>();
	
    private final static CacheFacade cacheFacade = CacheFacade.getInstance();
    
	private WebApplicationContext wac;

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain)
			throws IOException, ServletException {
		final HttpServletRequest request = (HttpServletRequest) req;
		final HttpServletResponse response = (HttpServletResponse) resp;
		final HttpSession session = request.getSession();
		final User user = (User) session.getAttribute("showtimes_login");
		final String uri = request.getRequestURI();
		logger.info("请求URL：" + uri + ",user:" + user);
		
		try {
			if (user != null) {
				setUserContext(request, user);
			} else {
				String token = request.getHeader("token");
				logger.info("currentUser token is :" +token);
				if(StringUtils.isNotEmpty(token)){
					wac = WebApplicationContextUtils.getWebApplicationContext(req.getServletContext());
					ITokenService tokenService =  (ITokenService)wac.getBean("tokenService");
					IUserService userService =  (IUserService)wac.getBean("userService");
					User comUser =userService.queryUserByToken(token);
					if(comUser==null){
						response.setStatus(401);
						response.setHeader("sessionstatus", "timeout");
						session.invalidate();
						return;
					}
					//验证token是否有效
					if(StringUtils.isBlank(token) || !tokenService.isTokenValid(token)){
						response.setStatus(401);
						response.setHeader("sessionstatus", "timeout");
						session.invalidate();
						// 清除无效token信息
						userService.cleanUserLoginInfo(comUser.getUserId());
						// 删除在线用户信息
						cacheFacade.delete("showtimes_login", comUser.getUserId());
						return;
					} else {
	                    User users =JSON.toJavaObject(JSON.parseObject(cacheFacade.get("showtimes_login", comUser.getUserId()).toString()), User.class);
	                    session.setAttribute("showtimes_login", users);
	                    setUserContext(request, users);
						chain.doFilter(request, response);
						return;
					}
				}else{
					if (isWhiteUri(uri)) {
						chain.doFilter(request, response);
						return;
					}else{
						response.setStatus(401);
						response.setHeader("sessionstatus", "timeout");
						session.invalidate();
						return;
					}
				}
			}
			chain.doFilter(request, response);
		}catch (Exception e) {
			throw e;
		}finally{
			RequestContext.remove();
		}
		
	}

	// 设置thread context，供后续服务直接获取当前用户相关信息
	private void setUserContext(HttpServletRequest request, User user) {
		
		Map<String, Object> attributes = new HashMap<String, Object>();
		attributes.put(RequestContext.USER_NAME, user.getUserName());
		attributes.put(RequestContext.USER_ID, user.getUserId());
		attributes.put(RequestContext.USER_TYPE, Integer.toString(user.getUserType()));
		RequestContext.setAttributes(attributes);
	}

	private boolean isWhiteUri(final String uri) {
		for (final String whiteUrl : WHITE_LIST) {
			if (uri.contains(whiteUrl)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void init(final FilterConfig config) throws ServletException {
		WHITE_LIST.add("login");
		WHITE_LIST.add("getConfig");
		WHITE_LIST.add("getToken");
		WHITE_LIST.add("shareList");
		WHITE_LIST.add("autoUpdate");
		WHITE_LIST.add("increaseReadCount");
		WHITE_LIST.add("userShareList");
		WHITE_LIST.add("increasePraiseCount");
		WHITE_LIST.add("comment");
		WHITE_LIST.add("shareDetail");
		
		
	}
}
